package com.gimi.cloud.jimi.commonService.InterfacePlatform.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.gimi.cloud.jimi.common.enums.ResponseCodeEnum;
import com.gimi.cloud.jimi.common.exception.MsgException;
import com.gimi.cloud.jimi.common.utils.StringUtil;
import com.gimi.cloud.jimi.commonService.InterfacePlatform.InterfacePlatformRequestService;
import com.gimi.cloud.jimi.dao.redis.IRedisService;
import com.gimi.cloud.jimi.dto.params.InterfcaeParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * gimi接口调用封装类
 * @author zhoufuhang
 * @time 2018年1月3日
 */
@Component
public class InterfaceUtil {
	
	@Autowired
	private IRedisService iRedisService;
	@Autowired
	private InterfacePlatformRequestService interfacePlatformRequestService;
	
	private final Logger log = LoggerFactory.getLogger(InterfaceUtil.class);
	
	public <T extends InterfcaeParam> Object call(T t) {
		String value = null;
		String config = iRedisService.get(t.getRedisKey());
		JSONObject configJson = JSONObject.fromObject(config);
		String param = null;
		if (!StringUtil.isEmpty(t.getInterfcaeParamKey())) {
			param = configJson.getString(t.getInterfcaeParamKey());
			JSONObject interfaceparamJson = JSONObject.fromObject(t);
			for (Object interfaceparam : interfaceparamJson.keySet()) {
				value = interfaceparamJson.getString(String.valueOf(interfaceparam));
				if (!StringUtil.isEmpty(value)) {
					param = param.replaceAll("#" + interfaceparam + "#", value);
				} 
			}
		} else {
			if (StringUtil.isEmpty(t.getInterfcaeParam())) {
				throw new MsgException(ResponseCodeEnum.UNKNOWN_ERROR);
			}
			param = t.getInterfcaeParam();
		}
		
		String result = null;
		log.info("接口请求：" + JSONObject.fromObject(param));
		try {
			result = interfacePlatformRequestService.sendApiPost(param);
		} catch (Exception e) {
			log.error("接口请求：" + JSONObject.fromObject(param));
			log.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage());
		}
		log.info("接口返回：" + result);
		if(StringUtil.isBlank(result)){
			throw new MsgException(ResponseCodeEnum.SERVICE_ERROR);
		}
		JSONObject resultJson = JSONObject.fromObject(result);
		String responseCode = resultJson.getJSONObject("head").getString("responseCode");
		if (responseCode == null || !"0000".equals(responseCode)) {
			throw new MsgException(ResponseCodeEnum.INTERFACE_ERROR);
		}
		if (!StringUtil.isEmpty(t.getInterfcaeResultKey())) {
			Map<String, Object> resultMap = new HashMap<>();
			getValues((JSON) resultJson.get("body"), configJson.getJSONArray(t.getInterfcaeResultKey()), 5, resultMap);
			t.setInterfcaeResult(resultMap);
		}
		
		return resultJson.get("body");
	}
	
	/**
	 * 根据规则便利json数据
	 * @param resultJSON 需要便利的json
	 * @param ruleJSONArray 规则json
	 * [
	 *	    {
	 *	        "key":"data",		需要便利json的key
	 *	        "condition":[       是否有判断条件
	 *	            {
	 *	                "values":"true",    判断条件的值
	 *	                "enum":"SUCCESSED", 条件不满足抛出的异常的枚举
	 *	                "msgKey":"message", 是否提示遍历json里的字段
	 *	                "conKey":"success"  判断条件的key
	 *	            }
	 *	        ],
	 *	        "next":[ ]					下一个需要便利的字段
	 *	    }
	 *	]
	 * 
	 * 
	 * @param depth 	递归深度 (递减)
	 * @param resultMap 返回值map
	 */
	public static void getValues(JSON resultJSON, JSONArray ruleJSONArray, int depth, Map<String, Object> resultMap) {
		if (depth < 1 || resultJSON == null || resultJSON.isEmpty() || ruleJSONArray == null || ruleJSONArray.isEmpty()) {
			return;
		}
		for (Object ruleObje : ruleJSONArray) {
			JSONObject ruleJSONObject = (JSONObject) ruleObje;
			//判断是array还是object
			if (resultJSON instanceof JSONObject) {
				JSONObject resultJSONObject = (JSONObject) resultJSON;
				getValues(resultJSONObject, ruleJSONObject, depth, resultMap);
			} else if (resultJSON instanceof JSONArray) {
				JSONArray resultJSONArray = (JSONArray) resultJSON;
				for (Object resultObj : resultJSONArray) {
					JSONObject resultJSONObject = (JSONObject) resultObj;
					getValues(resultJSONObject, ruleJSONObject, depth, resultMap);
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private static void getValues(JSONObject resultJSONObject, JSONObject ruleJSONObject, int depth, Map<String, Object> resultMap) {
		//根据规则判断是否取值
		if (ruleJSONObject.containsKey("condition")) {
			JSONArray condition = ruleJSONObject.getJSONArray("condition");
			for (Object object : condition) {
				JSONObject conditionJSONObject = (JSONObject) object;
				//如果规则校验失败
				if (StringUtil.isEmpty(conditionJSONObject.getString("conKey")) || StringUtil.isEmpty(resultJSONObject.getString(conditionJSONObject.getString("conKey"))) ||
						StringUtil.isEmpty(conditionJSONObject.getString("values")) || !resultJSONObject.getString(conditionJSONObject.getString("conKey")).equals(conditionJSONObject.getString("values"))) {
					if (StringUtil.isEmpty(conditionJSONObject.getString("enum"))) {
						throw new MsgException(ResponseCodeEnum.UNKNOWN_ERROR);
					}
					if (!conditionJSONObject.containsKey("msgKey") || StringUtil.isEmpty(conditionJSONObject.getString("msgKey"))) {
						throw new MsgException(ResponseCodeEnum.valueOf(conditionJSONObject.getString("enum")));
					} else {
						throw new MsgException(ResponseCodeEnum.valueOf(conditionJSONObject.getString("enum")), resultJSONObject.getString(conditionJSONObject.getString("msgKey")));
					}
				}
			}
		}
		//如果没有下一级则直接返回
		if (!ruleJSONObject.containsKey("next") || StringUtil.isEmpty(ruleJSONObject.getString("next"))) {
			//如果有多个值则装入数组中
			if (resultMap.containsKey(ruleJSONObject.getString("key"))) {
				Object resultObject = resultMap.get(ruleJSONObject.getString("key"));
				if (resultObject instanceof ArrayList<?>) {
					((ArrayList<Object>) resultObject).add(resultJSONObject.get(ruleJSONObject.getString("key")));
				} else {
					List<Object> list = new ArrayList<>();
					list.add(resultObject);
					list.add(resultJSONObject.get(ruleJSONObject.getString("key")));
					resultMap.put(ruleJSONObject.getString("key"), list);
				}
			} else {
				resultMap.put(ruleJSONObject.getString("key"), resultJSONObject.get(ruleJSONObject.getString("key")));
			}
			return;
		}
		//判断是下一级是否存在，是否有效
		if (!resultJSONObject.containsKey(ruleJSONObject.getString("key")) && StringUtil.isEmpty(resultJSONObject.getString(ruleJSONObject.getString("key")))) {
			//如果存在处理方案这直接处理(默认不进入下一级)
			if (ruleJSONObject.containsKey("notKey") && StringUtil.isEmpty(ruleJSONObject.getString("notKey"))) {
				throw new MsgException(ResponseCodeEnum.valueOf(ruleJSONObject.getString("notKey")));
			}
			return;
		} 
		getValues((JSON) resultJSONObject.get(ruleJSONObject.getString("key")), ruleJSONObject.getJSONArray("next"), --depth, resultMap);
	}
	
	
	public static void main(String[] args) {
		Map<String, Object> resultMap = new HashMap<>();
		String sde= "[\r\n" + 
				"        {\r\n" + 
				"            \"result\":\r\n" + 
				"            {\r\n" + 
				"                \"verifyCode\":\"iVBO…… \",\r\n" + 
				"                \"sid\":\"ccrc_02i05i05WY6RA0R7Y0n5i7nn7BE0Bfn0\"\r\n" + 
				"            },\r\n" + 
				"            \"message\":\"注册图片验证码获取成功\",\r\n" + 
				"            \"status\":1\r\n" + 
				"        }\r\n" + 
				"    ]\r\n" + 
				"";
		JSON json = JSONArray.fromObject(sde);
		String rule = "[{\"key\":\"result\",\"condition\":[{\"values\":\"1\",\"enum\":\"SUCCESSED\",\"msgKey\":\"message\",\"conKey\":\"status\"}],\"next\":[{\"key\":\"verifyCode\"},{\"key\":\"sid\"}]}]";
		getValues(json, JSONArray.fromObject(rule), 5, resultMap);
		System.out.println(resultMap);
		
	}
	
}
